home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
doc.lha
/
documentation
/
manual
/
object.mss
< prev
next >
Wrap
Text File
|
1987-06-30
|
11KB
|
270 lines
@part[OBJECT, root "TMAN.MSS"] @Comment{-*-System:TMAN-*-}
@chap[Objects]
@Tau[] is an @i[object-oriented] language. @Tau[] programs
are concerned for the most part with creating and manipulating
@iix[objects], which represent all data, and form the
currency of computation in @Tau[]. Particular objects are defined not
by bit patterns or by addresses within a computer but rather by their
behavior when called or when passed to procedures which manipulate them.
Objects are obtained most primitively through the use of @tc[QUOTE]
(page @pageref[QUOTE]), @tc[LAMBDA] (page @pageref[LAMBDA]), and @tc[OBJECT]
(page @pageref[OBJECT]) special forms, and less primitively by calling
procedures defined in the standard environment, e.g. @tc[CONS] and
@tc[COMPOSE], which create new objects or return existing ones. (An
implementation of @Tau[] would presumably define many such procedures
using more primitive object constructors; for example, @tc[COMPOSE]
might be defined by a @Tau[] program which employs @tc[LAMBDA] to
construct the composed procedure. Thus the question of what kinds of
objects are truly primitive and which are not is left unanswered by this
manual.)
@section[Literals]
As described in section @ref[CoreLanguageSection], some expressions
evaluate @qu"to themselves" or to copies of themselves. These include
numbers, strings, and characters, and are called
@i[self-evaluating literals.] However, some expressions, lists and
symbols in particular, do not evaluate to themselves. When an
expression yielding a particular constant value is required,
it is necessary to use @tc[QUOTE]. Self-evaluating literals
and quoted constants are called @iix[literals].
Although not all objects have external representations, some objects
which do have external representations have undefined evaluation
semantics. These include vectors (section @ref[VectorsSection]) and the
empty list. @tc[QUOTE] must also be used to obtain these values as
constants.
@info[NOTES="Special form"]
@desc[@el[](QUOTE @i[object]) @yl[] @i[object]]
Yields @i[object]. The @i[object] is not evaluated; thus @tc[QUOTE]
provides a literal notation for constants.
@begin[ProgramExample]
(QUOTE A) @ev[] A
(QUOTE (A B)) @ev[] (A B)
(QUOTE (+ X 8)) @ev[] (+ X 8)
(QUOTE (QUOTE A)) @ev[] (QUOTE A)
@end[ProgramExample]
Since @tc[QUOTE] is used so frequently, an abbreviated external syntax
is provided for @tc[QUOTE] forms: @tc['@i[object]] is an alternative
external representation for the list @tc[(QUOTE @i[object])].
@tindex[']
@begin[ProgramExample]
'A @ev[] A
'(A B) @ev[] (A B)
'(QUOTE A) @ev[] (QUOTE A)
''A @ev[] (QUOTE A)
@end[ProgramExample]
Objects returned by literal expressions are read-only; they should not
be altered using @tc[SET] or any other side-effecting form.
@EndDesc[QUOTE]
@section[Procedures]
A @i[procedure]@index[procedures] (or @i[routine]@index[routines])
is any object which may be called. Ordinarily, a procedure is called
as a result of the evaluation of a @i[call] (page @pageref[CallSemantics]).
The most primitive mechanism for creating procedures is the
@tc[LAMBDA] special form.
@IndexEntry[key = "Functions", text = "Functions, @i<see> Procedures"]
@dc{ Talk about why procedures are important; first-class citizenship;
surprising roles; etc. ...? }
@AnEquivE[Tfn="LAMBDA",Efn="CLOSURE"]
@info[NOTES="Special form",EQUIV="FUNCTION"]
@desc[@el[](LAMBDA @i[variables] . @i[body]) @yl[] @i[procedure]]
A @tc[LAMBDA]-expression evaluates to a procedure.
When the procedure is called, the @i[variables]
are bound to the arguments to the call, and the @i[body], an implicit
block, is evaluated. The call yields the value of the last form in the
@i[body].
@begin[ProgramExample]
((LAMBDA (X Y) (LIST Y X)) 7 'FOO) @ev[] (FOO 7)
@end[ProgramExample]
If @i[variables] is not a proper list, but ends in a symbol @i[x], then
the variable @i[x] will be bound to a list of the arguments beginning at
the position corresponding to @i[x].
@begin[ProgramExample]
((LAMBDA (X . Y) (LIST Y X)) 7 'FOO 'BAZ) @ev[] ((FOO BAZ) 7)
((LAMBDA Y Y) 7 'FOO 'BAZ) @ev[] (7 FOO BAZ)
@end[ProgramExample]
If any @i[variable] is @tc[()] instead of a symbol, then the
corresponding argument in a call is ignored. @dc{ ref @tc[IGNORE]! }
@i[Scoping:]@index[scope]@index[lexical scoping]
The values of the bound variables are apparent only in code lexically
contained in the body of the @tc[LAMBDA]-expression, and not to routines
@i[called] from the body. That is, like SCHEME and ALGOL and unlike
most Lisp dialects, @tau[] is a lexically scoped language, not a dynamically
scoped language.
@i[Closure:]@index[closure]
@dc{ Rewrite this paragraph. }
The @i[procedure] is said to be a @iix[closure] of the
@tc[LAMBDA]-expression in the current lexical environment. That is, when
@i[procedure] is called, the @i[body] is evaluated in an environment
which is the same as that in which the @tc[LAMBDA]-expression was
evaluated, augmented by the bindings of the @i[variables]. For example,
if @tc[Z] is mentioned in the @i[body], and it is not one of the
@i[variables], then it refers to whatever @tc[Z] was in scope when the
@tc[LAMBDA]-expression was evaluated, @i[not] (necessarily)
to the the variable @tc[Z] that is in scope when @i[procedure] is called.
@EndDesc[LAMBDA]
@section[Object identity]
Every object has @i[identity,] in the sense that one may determine
whether two given values are the same object.
@index[Equality predicates]
@index[Identity]
In the following:
@begin[ProgramExample]
(DEFINE A (LIST 'P 'Q))
(DEFINE B (LIST 'P 'Q))
@end[ProgramExample]
there is no way (other than @tc[EQ?]) to distinguish the two objects
which are the values of @tc[A] and @tc[B]. Nonetheless, since @tc[LIST]
is defined to return a new object each time it is called, the two
objects are distinct; and indeed, a side-effect to one object will not affect
the value of the other:
@begin[ProgramExample]
(SET (CAR A) 'R)
A @ev[] (R Q)
B @ev[] (P Q)
@end[ProgramExample]
Some system procedures and special forms create new objects, others
return objects which already exist. In some cases, it is not defined
which of the two happens; it is only guaranteed that some object with
appropriate characteristics is returned. For example, @tc[CONS] creates
new objects; @tc[QUOTE] expressions yield pre-existing constant objects;
and numerical routines such as @tc[+] may or may not create new numbers.
The @tc[EQ?] predicate primitively determines object identity.
@desc[@el[](EQ? @i[object1 object2]) @yl[] @i[boolean]]
Returns true if @i[object1] and @i[object2] are identically the same
object. @tc[EQ?] is the @i[finest] comparison predicate for
objects, in the sense that if @tc[EQ?] cannot distinguish two objects,
then neither can any other equality predicate. @dc{ what the??? }
@EndDesc[EQ?]
@desc[@el[](NEQ? @i[object1 object2]) @yl[] @i[boolean]]
@tc[NEQ?] is the logical complement of @tc[EQ?].
@begin[TEG]
(NEQ? @i[object1 object2]) @ce[] (NOT (EQ? @i[object1 object2]))
@end[TEG]
@EndDesc[NEQ?]
Uniqueness of literals (other than symbols and characters) isn't defined
in general. For example,
@begin[ProgramExample]
(EQ? '(A B C) '(A B C))
@end[ProgramExample]
may yield either true or false, depending on the implementation.
Two similar-looking literal expressions in different places
may or may not yield distinct objects.
However, a given literal expression will always yield the same object
each time it is evaluated. @dc{ forward reference }
@begin[ProgramExample]
(LET ((F (LAMBDA () '(A B C)))) (EQ? (F) (F))) @yl[] @r[true]
@end[ProgramExample]
@section[Symbols]
@label[symbols section] @Comment{ref. semantics chapter}
@iix[Symbols] are named objects which have wide applicability as
tokens and identifiers of various sorts. Symbols are uniquely
determined by their names, and have a convenient external syntax
by which they may be obtained.
Uniqueness of symbols @i[is] defined:
@begin[ProgramExample]
(EQ? 'FOO 'FOO) @ev[] @r[true]
@end[ProgramExample]
@dc{ Give details of external representation. Should we avoid defining
the \ syntax here? It really seems extraneous, and surely it shouldn't
be encouraged. }
@info[NOTES="Type predicate",EQUIV="SYMBOLP"]
@desc[(SYMBOL? @i[object]) @yl[] @i[boolean]]
Returns true if @i[object] is a symbol.
@EndDesc[SYMBOL?]
See also @tc[SYMBOL->STRING] and @tc[STRING->SYMBOL], page
@pageref[STRING->SYMBOL].
@section[Predicates and truth values]
Conditional expressions in @Tau[] (see section
@ref[ConditionalsSection]) usually involve the evaluation of a
@iixs[test] expression; the object yielded by the test is then used to
make a control decision, depending on whether the value is @iix[false]
or @iix[true]. There is one false value; this is a distinguished object
called @iix[null]. Any other value is considered to be true. A value
intended to be used in this way is called a @iixs[truth value].
@index[Conditionals]
A @iixs[predicate] is any procedure which yields truth values.
Predicates are typically given names which end in @tc[?],
e.g. @tc[NULL?] and @tc[EQ?]. Calls to predicates are
naturally used as test expressions.
An @iixs[equality predicate] is a two-argument predicate which is
side-effectless and unaffected by side-effects, and acts like an
equivalence relation in the mathematical sense.
@desc[@el[]NIL @yl[] @i[false]]
This system variable has as its value the object @i[null.] Null serves
two distinct purposes in @Tau[]: it is the standard false value,
as returned by test expressions and tested by conditionals; and it
is the @iix[empty list], a list which has no elements. Null's external
representation is @tc[()].
(Programmers with prior LISP experience should note that in most other
dialects of LISP, null and the symbol @tc[NIL] are identical. This
is not the case in @tau[]: @wt['NIL @ev[] NIL], but @wt[NIL @ev[]
()], and @wt[(EQ? NIL 'NIL)] is false.)
@EndDesc[NIL]
@info[IndexHack]
@desc[@el[]T @yl[] @i[true]]
The system variable @tc[T] has as its value a standard true value.
The identity of this value is unimportant, since any non-false value
is considered to be true for the purposes of tests.
@EndDesc[T]
@section[Types]
A @iixs[type] may be seen either as a collection of objects
with similar behavior, or as a characteristic function for such a
collection, or as the behavior characteristic of similar objects; these
views are equivalent.
A @iixs[type predicate] is a predicate which is defined on all objects and
whose value is not affected by any side-effects (that is, calling the
type predicate on a particular object will return the same value
regardless of the point at which it is called with respect to arbitrary
other computations). Type predicates are usually used to determine a
given object's membership in a type.
@dc{ is more discussion in order here? ... }